﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using System.IO.IsolatedStorage;
using System.IO;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using GameStateManagement;
using Microsoft.Phone.Shell;
using System.Xml.Serialization;

namespace PiratesOfBermuda
{
    public enum GameState { Playing, Paused, PlayerLose, PlayerWin, AllDead }

    public class GameProcessor
    {                
        // bien quan ly cac doi tuong trong game
        public Dictionary<string, MySprite> gameObjects;

        // cac doi tuong chinh trong game
        public Player player; // nguoi choi
        public int playerLifeRemained = 1;
        public int opponentLifeRemained = 1;

        public List<BasicEnemy> enemies; // tau dich

        public List<Whirl> whirls; // xoay nuoc

        public List<Island> islands; // dao

        public List<Rubble> rubbles; // vung tau dich bi chim

        //Textures Members
        public Texture2D backgroundTexture;
        public Texture2D explodeTexture;

        //Logic fields        
        public GameState gameState; // trang thai cua gmae
        protected bool isPlayerTurn; // kiem tra luot cua nguoi choi

        //Miscs
        public Random random;
        public List<Animation> explodeAnimations; // danh sach cac hieu ung no

        //protected ScreenManager screenManager;
        public Game game;
        public SpriteBatch spriteBatch;
        protected List<string> messages; // Bien dung de luu giu cac thong diep giao tiep khi choi che do multiplayer

        public GameProcessor(Game game, SpriteBatch spriteBatch)
        {
            this.game = game;
            this.spriteBatch = spriteBatch;
            random = new Random();

            //Khoi tao nhung doi tuong can su dung
            rubbles = new List<Rubble>();
            enemies = new List<BasicEnemy>();
            whirls = new List<Whirl>();
            islands = new List<Island>();
            explodeAnimations = new List<Animation>();
            gameObjects = new Dictionary<string, MySprite>();
            messages = new List<string>();

            //Dat tinh trang cua man choi
            gameState = GameState.Playing;
            isPlayerTurn = true;
        }

        #region Generate Methods
        public virtual void GenerateGameObjects()
        {
            GenerateWhirls();
            GenerateIslands();
            GenerateEnemies();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tempPlayer"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="name"></param>
        public void GeneratePlayer(ref Player tempPlayer, int x, int y, string name) 
        {
            if (tempPlayer == null || tempPlayer.X != x  || tempPlayer.Y != y)
            {
                string key = x.ToString() + "_" + y.ToString();
                tempPlayer = new Player(game, spriteBatch);
                if (name == "Client")
                    tempPlayer.InitializeClient();
                else
                    tempPlayer.Initialize();
                tempPlayer.Name = name;
                tempPlayer.X = x;
                tempPlayer.Y = y;
                gameObjects.Add(key, tempPlayer);
                tempPlayer.IsActive = true;
            }
        }
        
        
        /// <summary>
        /// Ham dung de khoi tao cac tau dich voi so luong ngau nhien va vi tri ngau nhien tren ban do
        /// </summary>
        /// 
        protected BasicEnemy GenerateEnemy(int x, int y)
        {
            BasicEnemy newAI = new BasicEnemy(game, spriteBatch, x, y);
            newAI.Initialize();
            gameObjects.Add(x.ToString() + "_" + y.ToString(), newAI);
            return newAI;
        }
        public void GenerateEnemies()
        {
            messages.Clear();
            // @Duy Quang (12/12/11) 
            // Chu y: code con cung -> nen mem hoa code qua XML 
            //int numEnemies = random.Next(6, Constants.NumOfMaxEnemies); // random so tau dich
            int numEnemies = 1;
            int x, y;
            int count = 0; // bien dem dung trong vong lap

            do
            {
                x = random.Next(0, Constants.MapX);
                y = random.Next(0, Constants.MapY);
                if (!(x >= 4 && x <= 6 && y >= 4 && y <= 6) && ((x > 0 && x < Constants.MapX) || (y > 0 && y < Constants.MapY)))
                    if (!gameObjects.ContainsKey(x.ToString() + "_" + y.ToString())) // Kiem tra doi tuong da duoc tao hay chua
                    {
                        enemies.Add(GenerateEnemy(x, y));
                        count++;
                        messages.Add("Init,Enemy," + x.ToString() + "," + y.ToString());
                    }
            } while (count < numEnemies);
        }
        
        
        /// <summary>
        /// Khoi tao 4 cai voi rong o 4 goc ban do
        /// </summary>
        /// 
        protected Whirl GenerateWhirl(int x, int y)
        {
            Whirl newWhirl = new Whirl(game, spriteBatch, x, y);
            newWhirl.Initialize();
            gameObjects.Add(x + "_" + y, newWhirl);            
            return newWhirl;
        }
        public void GenerateWhirls()
        {
            messages.Clear();

            int x, y;
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    x = i * 10; y = j * 10;
                    whirls.Add(GenerateWhirl(x, y));
                    messages.Add("Init,Whirl," + x + "," + y);
                }
            }           
        }
        
        
        /// <summary>
        /// Khoi tao cac hon dao tren ban do voi so luong ngau nhien nam trong khoang
        /// cho truoc
        /// </summary>
        /// 
        protected Island GenerateIsland(int x, int y)
        {
            Island newIsland = new Island(game, spriteBatch, x, y);
            newIsland.Initialize();
            gameObjects.Add(x.ToString() + "_" + y.ToString(), newIsland);               
            return newIsland;
        }
        public void GenerateIslands()
        {
            messages.Clear();
            int numIslands = random.Next(6, Constants.NumOfMaxIslands);
            int count = 0;

            do
            {
                int x = random.Next(0, Constants.MapX - 1); // - 1 de tranh tinh trang cac dao tao ngau nhien bao vay cac voi rong
                int y = random.Next(0, Constants.MapY - 1);

                if (!(x >= 3 && x <= 7 && y >= 3 && y <= 7)) // Kiem tra dieu kien dao tao ngau nhien ko duoc nam qua gan, hay bao boc tau cua nguoi choi
                {
                    if (!gameObjects.ContainsKey(x.ToString() + "_" + y.ToString()))
                    {
                        islands.Add(GenerateIsland(x, y));
                        count++;
                        messages.Add("Init,Island," + x + "," + y);
                    }
                }
            } while (count < numIslands);
        }
        #endregion        

        #region UPDATE    
        public virtual void Update(GameTime gameTime)
        {
            UpdateWhirl(gameTime);
            UpdateIsland(gameTime);
            UpdateRubble(gameTime);
            UpdateEnemies(gameTime);            
        }

        //Bien dung de danh dau doan code ben trong da thuc hien lan nao chua
        public bool isDone = false;

        /// <summary>
        /// Ham de kiem tra trang thai va xu ly cac hanh dong thich hop ung voi moi enemies
        /// </summary>
        /// <returns>True / False
        /// True: thong bao hanh dong cua cac enemies da thuc hien xong -> nhuong luot di lai cho nguoi choi
        /// False: Nguoc lai
        /// </returns>
        ///         
        protected bool handleEnemiesUpdateEvent()
        {
            bool flag = false;
            messages.Clear();
            //Kiem tra xem tat ca tau da di chuyen xong chua
            bool isAllEnemiesMoved = true;
            foreach (BasicEnemy enemy in enemies)
            {
                if (!(enemy.CurrentShipState == ShipState.Standby) || enemy.IsActive)
                {
                    isAllEnemiesMoved = false;
                    break;
                }
            }

            //Neu tau AI da di chuyen xong va block nay chua thuc hien thi thuc hien doan code sau
            //Bien isDone dung de danh dau xem doan code nay da thuc hien chua.
            if (isAllEnemiesMoved && !isDone)
            {
                foreach (BasicEnemy enemy in enemies)
                {
                    string lastKey = enemy.LastPosition.X + "_" + enemy.LastPosition.Y;
                    gameObjects.Remove(lastKey);
                    messages.Add("Update,RemoveEnemiesLastPosition");
                }

                foreach (BasicEnemy enemy in enemies)
                {
                    string key = enemy.X + "_" + enemy.Y;
                    if (!gameObjects.ContainsKey(key))
                    {
                        gameObjects.Add(key, enemy);
                        
                    }
                    else
                    {
                        Type type = gameObjects[key].GetType();
                        if (type == typeof(Player) || type == typeof(BasicEnemy))
                        {
                            gameObjects[key].Destroyed = true;
                            if (type == typeof(Player))
                            {
                                messages.Add("Update,MarkPlayerDestroyed," + enemy.X + "," + enemy.Y);
                            }
                            ReplaceWithRubble(new Point(enemy.X, enemy.Y));
                            messages.Add("Update,ReplaceWithRubble," + enemy.X + "," + enemy.Y);
                        }
                        enemy.Destroyed = true;
                        Animation explodeAnimation = new Animation(explodeTexture, new Point(20, 28), new Point(15, 1), new Point(enemy.X, enemy.Y));
                        explodeAnimations.Add(explodeAnimation);
                        explodeAnimation.PlayFromFrameIndex(0);
                        messages.Add("Update,AddExplodeAnimation," + enemy.X + "," + enemy.Y);
                    }
                }
                //Loai bo cac enemy bi danh dau (kiet suc, ko con kha nang chien dau ^_^)
                int count = 0;
                while (count < enemies.Count)
                {
                    if (enemies[count].Destroyed)
                    {
                        enemies.RemoveAt(count);
                        messages.Add("Update,RemoveDestroyedEnemy," + count);
                        AudioManager.PlaySound("Explode");
                    }
                    else
                        count++;
                }
                messages.Add("Update,UpdateEnemyPosition");
                //Danh dau lai la doan code nay da thuc hien xong
                isDone = true;
            }
            //Neu doan code tren da thuc hien xong
            else if (isAllEnemiesMoved && isDone)
            {
                //Kiem tra xem hieu ung no da thuc hien xong het chua
                bool isExplodeAnimationsPlayed = true;
                foreach (Animation a in explodeAnimations)
                {
                    if (a.IsActive)
                    {
                        a.Update();
                        isExplodeAnimationsPlayed = false;
                    }
                }
                //Neu da thuc hien xong thi chuyen luot lai cho nguoi choi
                if (explodeAnimations != null && isExplodeAnimationsPlayed)
                {
                    flag = true;
                    //Clear list hieu ung no
                    explodeAnimations.Clear();
                    isDone = false;
                }
            }
            return flag;
        }

        protected virtual void UpdateEnemies(GameTime gameTime) { }        

        //2 bien dung de kiem tra xem 2 qua cannon da thuc hien xong nhiem vu chua
        protected bool isCannon1Hit = false;
        protected bool isCannon2Hit = false;

        protected virtual void removeSpecifiedShip(string key)
        {
            BasicEnemy toRemove = (BasicEnemy)gameObjects[key]; // @Duy Quang: sua lai polymorphism: 
                                                                // Ship toRemove = (BasicEnemy) gameObjects[key];
            enemies.Remove((BasicEnemy)toRemove);
        }        

        

        protected virtual void UpdatePlayer(GameTime gameTime)
        {
            UpdateCustomPlayer(ref player, gameTime);
        }
        protected void UpdateCustomPlayer(ref Player tempPlayer, GameTime gameTime)
        {
            messages.Clear();
            //neu tau nguoi choi dang o trang thai Attacking
            if (tempPlayer.CurrentShipState == ShipState.Attacking)
            {
                handlePlayerAttackingEvent(ref tempPlayer);   
            }
            //Kiem tra xem luot choi truoc cua AI, tau minh co bi dam trung khong
            if (tempPlayer.Destroyed)
            {
                handlePlayersDestroyedEvent(ref tempPlayer);               
            }
            else if (enemies.Count == 0 && tempPlayer.Name == "Single")
                gameState = GameState.PlayerWin;

            tempPlayer.Update(gameTime);
        }
        protected void handlePlayerAttackingEvent(ref Player tempPlayer)
        {
            processCannonAttacks(ref tempPlayer, 1, tempPlayer.cannon.q1.Count,
                tempPlayer.cannon.P1, tempPlayer.cannon.Is1Exploded, ref isCannon1Hit);
            processCannonAttacks(ref tempPlayer, 2, tempPlayer.cannon.q2.Count,
                tempPlayer.cannon.P2, tempPlayer.cannon.Is2Exploded, ref isCannon2Hit);

            //Neu ca 2 qua cannon da thuc hien xong nhiem vu cua minh chuyen ve che do Standby
            if (!tempPlayer.cannon.IsAnimating)
            {
                tempPlayer.CurrentShipState = ShipState.Standby;
                tempPlayer.IsActive = false;
                isCannon1Hit = false;
                isCannon2Hit = false;
            }
        }
        protected void processCannonAttacks(ref Player tempPlayer, int explodePos, int effectsCount, Point position,
            bool cannonExplodedState, ref bool cannonHitState)
        {
            //Kiem tra khi hieu ung ban ra cannon da thuc hien xong
            if (effectsCount == 0 )
            {
                //Neu hieu ung phu (no hoac rot xuong nuoc) chua xay ra thi cho no chay
                if (explodePos == 1 && tempPlayer.cannon.lowerExplodeAnimation != null)
                {
                    if (!tempPlayer.cannon.lowerExplodeAnimation.IsPlayed)
                        tempPlayer.cannon.MakeLowerExlode();
                }
                else if (explodePos == 2 && tempPlayer.cannon.upperExplodeAnimation != null)
                {
                    if (!tempPlayer.cannon.upperExplodeAnimation.IsPlayed)
                        tempPlayer.cannon.MakeUpperExplode();
                }

            //Neu nhu qua cannon 1 ban trung tau dich thi cap nhat lai gameObject 
                //va xoa doi tuong enemy ra khoi danh sach quan ly
                //Dong thoi play sound hieu ung no
                if (cannonExplodedState && !cannonHitState)
                {
                    string key = position.X.ToString() + "_" + position.Y.ToString();
                    removeSpecifiedShip(key);
                    ReplaceWithRubble(position);
                    AudioManager.PlaySound("Explode");
                    cannonHitState = true;
                }
                //Neu cannon 1 chi roi xuong nuoc thi play am thanh rot xuong nuoc
                if (!cannonExplodedState && !cannonHitState)
                {
                    AudioManager.PlaySound("Sink");
                }
            }
        }
        protected virtual bool handlePlayersDestroyedEvent(ref Player tempPlayer)
        {
            bool alive = true;
            //Neu van con mang thi hoi sinh
            if (tempPlayer.LifeRemained > 0)
            {
                tempPlayer.LifeRemained = --playerLifeRemained;

                Point newPosition = GenerateNewPositionForPlayer();
                GeneratePlayer(ref tempPlayer, newPosition.X, newPosition.Y, tempPlayer.Name);
                messages.Add("Update," + tempPlayer.Name + "Respawn," + tempPlayer.X + "," + tempPlayer.Y);
            }
            //Con neu het mang thi chuyen gameState sang ket thuc game
            else
            {
                if (tempPlayer.Name != "Host")
                {
                    //Truong hop hoa
                    if (enemies.Count == 0)
                        gameState = GameState.AllDead;
                    else
                        //Truong hop nguoi choi thua
                        gameState = GameState.PlayerLose;
                }
                tempPlayer.CurrentShipState = ShipState.Ended;
                tempPlayer.Destroyed = false;
                messages.Add("Update," + tempPlayer.Name + "PlayerEnded");
                alive = false;
            }
            return alive;
        }
        

        public void UpdateWhirl(GameTime gameTime)
        {
            foreach (Whirl whirl in whirls)
            {
                whirl.Update(gameTime);
            }
        }
        
        public void UpdateIsland(GameTime gameTime)
        {
            foreach (Island island in islands)
            {
                island.Update(gameTime);
            }
        }

        public void UpdateRubble(GameTime gameTime)
        {
            foreach (Rubble rub in rubbles)
            {
                if (rub.IsActive)
                    rub.Update(gameTime);
            }
        }
        #endregion

        #region Draw        
        /// <summary>
        /// Phuong thuc chinh dung de kiem tra trang thai game va cap nhat su kien ve doi tuong tren man hinh
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="font">Font chu cua game</param>
        public virtual void Draw(GameTime gameTime, SpriteFont font)
        {
            spriteBatch.Begin();
            DrawBackground();
            CheckAndDrawGameObjects(gameTime);
            CheckAndDrawAnimations();

            // Kiem tra trang thai cua game
            if (gameState != GameState.Playing)
            {
                switch (gameState)
                {
                    case GameState.PlayerWin:
                        spriteBatch.DrawString(font, "Player Win !", new Vector2(0, 0), Color.SandyBrown);
                        break;
                    case GameState.PlayerLose:
                        spriteBatch.DrawString(font, "Player Lose !", new Vector2(0, 0), Color.SandyBrown);
                        break;
                    case GameState.AllDead:
                        spriteBatch.DrawString(font, "All Dead !", new Vector2(0, 0), Color.SandyBrown);
                        break;
                }
            }
            spriteBatch.End();
        }

        public void DrawGameObjects(GameTime gameTime)
        {
            DrawWhirl(gameTime);
            DrawIsland(gameTime);
            DrawRubble(gameTime);
            DrawEnemies(gameTime);
            DrawPlayer(gameTime);
        }

        public void DrawBackground()
        {
            spriteBatch.Draw(backgroundTexture, new Vector2(0, 0), Color.White);
        }
        public void DrawEnemies(GameTime gameTime)
        {
            foreach (BasicEnemy enemy in enemies)
            {
                enemy.Draw(gameTime);
            }
        }
        public void DrawWhirl(GameTime gameTime)
        {
            foreach (Whirl whirl in whirls)
            {
                whirl.Draw(gameTime);
            }
        }
        public void DrawIsland(GameTime gameTime)
        {
            foreach (Island island in islands)
            {
                island.Draw(gameTime);
            }
        }
        public void DrawRubble(GameTime gameTime)
        {
            foreach (Rubble rub in rubbles)
            {
                if (rub.IsActive)
                    rub.Draw(gameTime);
            }
        }
        protected virtual void DrawPlayer(GameTime gameTime)
        {
            player.Draw(gameTime);
        }       

        protected void DrawExplodeAnimations()
        {
            foreach (Animation a in explodeAnimations)
            {
                if (a.IsActive)
                    a.Draw(spriteBatch);
            }
        }        

        protected virtual void CheckAndDrawAnimations() {}

        protected virtual void CheckAndDrawGameObjects(GameTime gameTime)
        {
            DrawGameObjects(gameTime);
        }

        
        #endregion

        #region Player Helper Method
        /// <summary>
        /// Ham kiem tra vi tri ma nguoi choi chon co the thao tac duoc        
        /// </summary>
        /// <param name="point">Vi tri ma nguoi dung dang thao tac</param>
        /// <returns>
        /// return -1 neu ko di chuyen dc
        /// return 1 neu Di chuyen thong thuong
        /// return 2 neu di chuyen vao vung teleport
        /// return 3 neu tan cong
        /// </returns>
        protected int CanMove(Point point)
        {
            //Kiem tra xem co phai nguoi choi tan cong
            if (point.X == player.X && point.Y == player.Y)
                return 3;

            //2 bien cod1 va cod2 dung de kiem tra xem co thuoc pham vi hay khong.
            // theo truc X
            bool cod1 = (point.Y == player.Y) && Math.Abs(point.X - player.X) == 1;
            // theo truc Y
            bool cod2 = (point.X == player.X) && Math.Abs(point.Y - player.Y) == 1;

            //Tao khoa dung de kiem tra trong gameObjects
            string key = point.X.ToString() + "_" + point.Y.ToString();

            //Neu trong pham vi co the di chuyen dc
            if (cod1 || cod2)
            {
                if (gameObjects.ContainsKey(key))
                {
                    //Neu di vao vung teleport
                    if (gameObjects[key].GetType() == typeof(Whirl))
                        return 2;
                    //Neu dam dau vao tau dich :| (Lieu`)
                    else if (gameObjects[key].GetType() == typeof(BasicEnemy))
                        return 4;
                }
                // Di chuyen binh thuong
                if (!gameObjects.ContainsKey(key))
                    return 1;
            }
            return -1;
        }

        /// <summary>
        /// Khi player di vao vung xoay hoac khi nguoi choi hoi sinh can phat sinh 1 vi tri de xuat hien
        /// </summary>
        /// <returns>Vi tri moi</returns>
        protected Point GenerateNewPositionForPlayer()
        {
            int x, y;
            bool flag = false;
            do
            {
                x = random.Next(0, 10);
                y = random.Next(0, 10);

                if (!gameObjects.ContainsKey(x.ToString() + "_" + y.ToString()))
                    flag = true;
            } while (!flag);
            return new Point(x, y);
        }
        
        /// <summary>
        /// Ham dung de kiem tra xem tau cua nguoi choi co the tan cong duoc tau nao
        /// Ham nay dong thoi cung xu ly luon viec neu tau dich bi ban trung thi se dua vao trang thai
        /// cho duoc Destroyed, dong thoi thay the vi tri do bang 1 cai dau lau xuong cheo, ben canh do
        /// them vao cac animation explode hoac cannon roi xuong nuoc
        /// </summary>
        /// <returns>Tra ve danh sach toi da 2 diem ma tau tan cong (co the trung hoac khong)</returns>
        /// 
        protected void CheckHit(out Point? p1, out bool is1Exploded, out Point? p2, out bool is2Exploded)
        {
            bool flag1 = false, flag2 = false;
            p1 = Point.Zero;
            p2 = Point.Zero;

            if (player.MainSailDirection == MainSailDirections.East || player.MainSailDirection == MainSailDirections.West)
            {
                for (int i = 1; i <= Cannon.AttackRange; i++)
                {
                    string key = player.X.ToString() + "_" + (player.Y - i).ToString();
                    if (gameObjects.ContainsKey(key) && !flag1)
                        if (gameObjects[key].GetType() == typeof(BasicEnemy) || gameObjects[key].GetType() == typeof(Player))
                        {
                            flag1 = true;
                            p1 = new Point(player.X, player.Y - i);
                        }

                    key = player.X.ToString() + "_" + (player.Y + i).ToString();
                    if (gameObjects.ContainsKey(key) && !flag2)
                        if (gameObjects[key].GetType() == typeof(BasicEnemy) || gameObjects[key].GetType() == typeof(Player))
                        {
                            flag2 = true;
                            p2 = new Point(player.X, player.Y + i);
                        }
                }
                if (!flag1)
                {
                    if (player.Y == 0)
                        p1 = null;
                    else if (player.Y - Cannon.AttackRange <= 0)
                        p1 = new Point(player.X, 0);
                    else
                        p1 = new Point(player.X, player.Y - Cannon.AttackRange);
                }
                if (!flag2)
                {
                    if (player.Y == 10)
                        p2 = null;
                    else if (player.Y + Cannon.AttackRange >= 10)
                        p2 = new Point(player.X, 10);
                    else
                        p2 = new Point(player.X, player.Y + Cannon.AttackRange);
                }
            }
            else
            {
                for (int i = 1; i <= Cannon.AttackRange; i++)
                {
                    string key = (player.X - i).ToString() + "_" + player.Y.ToString();
                    if (gameObjects.ContainsKey(key) && !flag1)
                        if (gameObjects[key].GetType() == typeof(BasicEnemy) || gameObjects[key].GetType() == typeof(Player))
                        {
                            flag1 = true;
                            p1 = new Point(player.X - i, player.Y);
                        }

                    key = (player.X + i).ToString() + "_" + player.Y.ToString();
                    if (gameObjects.ContainsKey(key) && !flag2)
                        if (gameObjects[key].GetType() == typeof(BasicEnemy) || gameObjects[key].GetType() == typeof(Player))
                        {
                            flag2 = true;
                            p2 = new Point(player.X + i, player.Y);
                        }
                }
                if (!flag1)
                {
                    if (player.X == 0)
                        p1 = null;
                    else if (player.X - Cannon.AttackRange <= 0)
                        p1 = new Point(0, player.Y);
                    else
                        p1 = new Point(player.X - Cannon.AttackRange, player.Y);
                }
                if (!flag2)
                {
                    if (player.X == 10)
                        p2 = null;
                    else if (player.X + Cannon.AttackRange >= 10)
                        p2 = new Point(10, player.Y);
                    else
                        p2 = new Point(player.X + Cannon.AttackRange, player.Y);
                }
            }
            is1Exploded = flag1;
            is2Exploded = flag2;
        }

        /// <summary>
        /// Ham dung de thay the cac ship bi huy va thay the vao do la 
        /// 1 cai dau lau xuong cheo
        /// </summary>
        /// <param name="point">Toa do X can thay the</param>
        protected void ReplaceWithRubble(Point point)
        {
            string key = point.X.ToString() + "_" + point.Y.ToString();
            if (!gameObjects.ContainsKey(key) || !(gameObjects[key].GetType() == typeof(Rubble)))
            {
                Rubble newRubble = new Rubble(game, spriteBatch, point.X, point.Y);
                newRubble.Initialize();
                newRubble.IsActive = true;
                rubbles.Add(newRubble);
                gameObjects[key] = newRubble;
            }
        }

        public virtual void HandleInput(List<GestureSample> gestures) { }

        protected void HandleUserInput(List<GestureSample> gestures, string userType)
        {
            messages.Clear();

            foreach (GestureSample gesture in gestures)
            {
                if (gesture.GestureType == GestureType.Tap && player.CurrentShipState == ShipState.Standby)
                {

                    Point pnt = MyGameHelper.ConvertToMapCoordinate(gesture);

                    if (pnt.X != -1 && pnt.Y != -1)
                    {
                        int retvalue = CanMove(pnt);
                        if (retvalue != -1)
                        {
                            player.IsActive = true;
                        }
                        switch (retvalue)
                        {
                            case 1:
                                gameObjects.Remove(player.X.ToString() + "_" + player.Y.ToString());
                                gameObjects.Add(pnt.X.ToString() + "_" + pnt.Y.ToString(), player);
                                player.Move(pnt.X, pnt.Y);
                                messages.Add("Move," + userType + "," + pnt.X.ToString() + "," + pnt.Y.ToString());
                                AudioManager.PlaySound("MoveGood");
                                break;
                            case 2:
                                Point newPoint = GenerateNewPositionForPlayer();
                                gameObjects.Remove(player.X.ToString() + "_" + player.Y.ToString());
                                gameObjects.Add(newPoint.X.ToString() + "_" + newPoint.Y.ToString(), player);
                                player.MoveAndWhirl(pnt, newPoint);
                                messages.Add("MoveAndWhirl," + userType + "," + pnt.X.ToString() + "," + pnt.Y.ToString() +
                                    "," + newPoint.X.ToString() + "," + newPoint.Y.ToString());
                                AudioManager.PlaySound("MoveGood");
                                break;
                            case 3:
                                Point? p1, p2;
                                bool is1Exploded, is2Exploded;
                                CheckHit(out p1, out is1Exploded, out p2, out is2Exploded);
                                player.Fire(p1, is1Exploded, p2, is2Exploded);
                                if (userType != null)
                                {
                                    if (p1 == null && p2 == null)
                                    {
                                        messages.Add("Fire,null,null,null,null,null,null");
                                    }
                                    else if (p1 != null && p2 == null)
                                    {
                                        messages.Add("Fire," + p1.Value.X + "," + p1.Value.Y + "," +
                                            is1Exploded.ToString() + ",null,null,null");
                                    }
                                    else if (p1 == null && p2 != null)
                                    {
                                        messages.Add("Fire,null,null,null," + p2.Value.X + "," +
                                        p2.Value.Y + "," + is2Exploded.ToString());
                                    }
                                    else
                                        messages.Add("Fire," + p1.Value.X + "," + p1.Value.Y + "," + is1Exploded.ToString() +
                                            "," + p2.Value.X + "," + p2.Value.Y + "," + is2Exploded.ToString());
                                }

                                AudioManager.PlaySound("Boom");
                                break;
                        }
                    }
                }
            }
        }
        #endregion
    }
}